今天群里有人问了一个问题:忘记了ods电子表格文档的密码,怎么办?
我简单想了想,得出简单结论:如果你大概知道自己当时设置的密码的规律(比如,密码的长度,密码中包含哪些字符,是纯数字还是数字字母组合),那么可以通过编程的方式通过依次尝试的暴力破解方式找到密码。
以下是初步的代码。例子中使用的虽然是一个ods文档,但理论上任何能通过LibreOffice打开的文件都适用。
# -*- coding: utf-8 -*-
''' Simple python script to hack an office document password.
Usage:
1. Start a LibreOffice process (headless mode):
/opt/libreoffice/program/soffice.bin --accept=socket,host="localhost,port=2002;urp;" --headless
2. Run the script using the python binary bundled with LibreOffice:
/opt/libreoffice/program/python /home/suokunlong/Documents/hack.py
'''
import random
import uno
from com.sun.star.beans import PropertyValue
ods = "file:////home/suokunlong/Documents/test.ods"
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext)
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx)
arg_pw = PropertyValue()
arg_pw.Name = "Password"
model = None
possibleDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
passwordLength = 6
# When fileopen is successful, loadComponentFromURL returns a com::sun::star::lang::XComponent instance.
# Otherwise, it returns NULL.
# Try each password to see wether the returned value is true.
while not model:
possiblePassword = ""
for i in range(0, passwordLength):
rd = random.randint(0, len(possibleDigits)-1)
possiblePassword += possibleDigits[rd]
arg_pw.Value = possiblePassword
print(possiblePassword)
model = desktop.loadComponentFromURL(ods, "_blank", 0, (arg_pw,))
print("The password of the document is: ", password)
当然,这种方法效率会比较低,通过从可能的密码字符中随机组合的方式猜测、并且是单线程处理的情况下,可能需要跑很长时间才能中招。可以通过多线程、常用密码字典等、甚至是GPU计算等方式进行优化。
发表回复